/**
 * 📈 消费习惯分析服务
 * 分析用户的消费时间、类别、商户等习惯模式
 */

const db = require('../config/database');
const { predictFuture } = require('../utils/stats');
const { 
  analyzeSubcategoryDistribution, 
  analyzeTopMerchants,
  enhanceRecords
} = require('./category-classifier');

class HabitAnalyzer {
  /**
   * 综合习惯分析
   */
  static async analyzeHabits(userId, bookId, startDate, endDate) {
    try {
      return {
        timeAnalysis: await this.analyzeTimePatterns(userId, bookId, startDate, endDate),
        categoryAnalysis: await this.analyzeCategoryPreferences(userId, bookId, startDate, endDate),
        subcategoryAnalysis: await this.analyzeSubcategories(userId, bookId, startDate, endDate),
        merchantAnalysis: await this.analyzeMerchantFrequency(userId, bookId, startDate, endDate),
        trendAnalysis: await this.analyzeTrends(userId, bookId, startDate, endDate),
        consumptionSummary: await this.generateConsumptionSummary(userId, bookId, startDate, endDate)
      };
    } catch (error) {
      console.error('综合习惯分析失败:', error);
      throw error;
    }
  }

  /**
   * 时间模式分析
   */
  static async analyzeTimePatterns(userId, bookId, startDate, endDate) {
    try {
      // 按小时统计
      const [hourlyData] = await db.query(`
        SELECT 
          HOUR(date) as hour,
          COUNT(*) as count,
          SUM(amount) as amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
        GROUP BY HOUR(date)
        ORDER BY hour
      `, [userId, bookId, startDate, endDate]);

      // 按星期统计
      const [weekdayData] = await db.query(`
        SELECT 
          DAYOFWEEK(date) as dayofweek,
          COUNT(*) as count,
          SUM(amount) as amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
        GROUP BY DAYOFWEEK(date)
        ORDER BY dayofweek
      `, [userId, bookId, startDate, endDate]);

      const weekdayNames = ['', '周日', '周一', '周二', '周三', '周四', '周五', '周六'];
      
      return {
        hourly: hourlyData.map(d => ({
          hour: d.hour,
          count: d.count,
          amount: parseFloat(d.amount || 0)
        })),
        weekly: weekdayData.map(d => ({
          day: weekdayNames[d.dayofweek],
          dayIndex: d.dayofweek,
          count: d.count,
          amount: parseFloat(d.amount || 0)
        })),
        insights: this.generateTimeInsights(hourlyData, weekdayData)
      };
    } catch (error) {
      console.error('时间模式分析失败:', error);
      throw error;
    }
  }

  /**
   * 生成时间洞察
   */
  static generateTimeInsights(hourlyData, weekdayData) {
    const insights = [];

    try {
      if (hourlyData && hourlyData.length > 0) {
        // 找出高峰时段
        const maxHour = hourlyData.reduce((max, d) => 
          parseFloat(d.amount) > parseFloat(max.amount) ? d : max, 
          hourlyData[0]
        );
        insights.push(`消费高峰时段：${maxHour.hour}点，消费￥${parseFloat(maxHour.amount).toFixed(2)}`);
      }

      if (weekdayData && weekdayData.length > 0) {
        // 工作日vs周末
        const workdayTotal = weekdayData
          .filter(d => d.dayofweek >= 2 && d.dayofweek <= 6)
          .reduce((sum, d) => sum + parseFloat(d.amount || 0), 0);
        
        const weekendTotal = weekdayData
          .filter(d => d.dayofweek === 1 || d.dayofweek === 7)
          .reduce((sum, d) => sum + parseFloat(d.amount || 0), 0);
        
        if (weekendTotal > workdayTotal * 0.4) {
          insights.push('周末消费占比较高，建议注意节制');
        }
      }
    } catch (error) {
      console.error('生成时间洞察失败:', error);
    }

    return insights;
  }

  /**
   * 类别偏好分析
   */
  static async analyzeCategoryPreferences(userId, bookId, startDate, endDate) {
    try {
      const [data] = await db.query(`
        SELECT 
          category,
          COUNT(*) as count,
          SUM(amount) as amount,
          AVG(amount) as avg_amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
        GROUP BY category
        ORDER BY amount DESC
      `, [userId, bookId, startDate, endDate]);

      const total = data.reduce((sum, d) => sum + parseFloat(d.amount || 0), 0);

      return data.map(d => ({
        category: d.category,
        count: d.count,
        amount: parseFloat(d.amount || 0),
        avg_amount: parseFloat(d.avg_amount || 0),
        percentage: total > 0 ? ((parseFloat(d.amount) / total) * 100).toFixed(1) : '0.0'
      }));
    } catch (error) {
      console.error('类别偏好分析失败:', error);
      throw error;
    }
  }

  /**
   * 商户频率分析
   */
  static async analyzeMerchantFrequency(userId, bookId, startDate, endDate) {
    try {
      const [data] = await db.query(`
        SELECT 
          remark as merchant,
          COUNT(*) as count,
          SUM(amount) as amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
          AND remark IS NOT NULL AND remark != ''
        GROUP BY remark
        HAVING count >= 2
        ORDER BY count DESC, amount DESC
        LIMIT 10
      `, [userId, bookId, startDate, endDate]);

      return data.map(d => ({
        merchant: d.merchant,
        count: d.count,
        amount: parseFloat(d.amount || 0),
        avg_amount: parseFloat(d.amount || 0) / d.count
      }));
    } catch (error) {
      console.error('商户频率分析失败:', error);
      throw error;
    }
  }

  /**
   * 趋势分析
   */
  static async analyzeTrends(userId, bookId, startDate, endDate) {
    try {
      // 按月统计
      const [monthlyData] = await db.query(`
        SELECT 
          DATE_FORMAT(date, '%Y-%m') as month,
          SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END) as income,
          SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END) as expense
        FROM records
        WHERE user_id = ? AND book_id = ?
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
        GROUP BY DATE_FORMAT(date, '%Y-%m')
        ORDER BY month
      `, [userId, bookId, startDate, endDate]);

      const result = monthlyData.map(d => ({
        month: d.month,
        income: parseFloat(d.income || 0),
        expense: parseFloat(d.expense || 0),
        balance: parseFloat(d.income || 0) - parseFloat(d.expense || 0)
      }));

      // 如果有足够数据，进行未来3个月预测
      if (result.length >= 3) {
        const expenseHistory = result.map(d => d.expense);
        const predictions = predictFuture(expenseHistory, 3);
        
        result.predictions = predictions.map((value, index) => ({
          month: this.getNextMonth(result[result.length - 1].month, index + 1),
          predicted_expense: value,
          is_prediction: true
        }));
      }

      return result;
    } catch (error) {
      console.error('趋势分析失败:', error);
      throw error;
    }
  }

  /**
   * 获取下N个月的月份字符串
   */
  static getNextMonth(currentMonth, monthsAhead) {
    const [year, month] = currentMonth.split('-').map(Number);
    const date = new Date(year, month - 1 + monthsAhead, 1);
    return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
  }

  /**
   * 子类别分析（增强功能）
   * 对每个大类别进行细分分析
   */
  static async analyzeSubcategories(userId, bookId, startDate, endDate) {
    try {
      // 获取所有支出记录
      const [records] = await db.query(`
        SELECT category, remark, amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
      `, [userId, bookId, startDate, endDate]);

      // 使用分类识别服务分析子类别
      const subcategoryStats = analyzeSubcategoryDistribution(records);

      // 转换为前端友好的格式
      const result = [];
      for (const [category, subcategories] of Object.entries(subcategoryStats)) {
        const categoryTotal = Object.values(subcategories).reduce((sum, sub) => sum + sub.amount, 0);
        
        const subcategoryList = Object.entries(subcategories)
          .map(([subcategory, stats]) => ({
            name: subcategory,
            count: stats.count,
            amount: parseFloat(stats.amount.toFixed(2)),
            percentage: categoryTotal > 0 ? parseFloat(((stats.amount / categoryTotal) * 100).toFixed(1)) : 0
          }))
          .sort((a, b) => b.amount - a.amount);

        result.push({
          category,
          total: parseFloat(categoryTotal.toFixed(2)),
          subcategories: subcategoryList
        });
      }

      return result.sort((a, b) => b.total - a.total);
    } catch (error) {
      console.error('子类别分析失败:', error);
      throw error;
    }
  }

  /**
   * 生成消费模式总结（自然语言）
   * 基于数据生成人性化的消费习惯描述
   */
  static async generateConsumptionSummary(userId, bookId, startDate, endDate) {
    try {
      // 获取基础数据
      const [summary] = await db.query(`
        SELECT 
          COUNT(*) as total_count,
          SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END) as total_income,
          SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END) as total_expense,
          SUM(CASE WHEN type = 'income' THEN 1 ELSE 0 END) as income_count,
          SUM(CASE WHEN type = 'expense' THEN 1 ELSE 0 END) as expense_count
        FROM records
        WHERE user_id = ? AND book_id = ?
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
      `, [userId, bookId, startDate, endDate]);

      const stats = summary[0];
      const netIncome = parseFloat(stats.total_income || 0) - parseFloat(stats.total_expense || 0);
      const savingRate = stats.total_income > 0 ? (netIncome / parseFloat(stats.total_income) * 100) : 0;
      const avgExpense = stats.expense_count > 0 ? parseFloat(stats.total_expense || 0) / stats.expense_count : 0;

      // 获取分类占比
      const [categoryStats] = await db.query(`
        SELECT 
          category,
          COUNT(*) as count,
          SUM(amount) as amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
        GROUP BY category
        ORDER BY amount DESC
      `, [userId, bookId, startDate, endDate]);

      // 获取商户数据（用于识别消费特征）
      const [records] = await db.query(`
        SELECT category, remark, amount
        FROM records
        WHERE user_id = ? AND book_id = ? AND type = 'expense'
          AND DATE(date) BETWEEN ? AND ?
          AND is_deleted != 1
      `, [userId, bookId, startDate, endDate]);

      const topMerchants = analyzeTopMerchants(records, 5);

      // 生成自然语言总结
      const insights = [];

      // 1. 收支概况
      if (stats.total_income > 0) {
        insights.push({
          type: 'income_expense',
          title: '收支概况',
          content: `本期共记账${stats.total_count}笔，收入${stats.income_count}笔（¥${parseFloat(stats.total_income || 0).toFixed(2)}），支出${stats.expense_count}笔（¥${parseFloat(stats.total_expense || 0).toFixed(2)}），净${netIncome >= 0 ? '结余' : '超支'}¥${Math.abs(netIncome).toFixed(2)}。`
        });
      }

      // 2. 储蓄习惯
      if (savingRate >= 20) {
        insights.push({
          type: 'saving_rate',
          level: 'good',
          title: '储蓄习惯良好',
          content: `储蓄率${savingRate.toFixed(1)}%，您有较好的储蓄习惯，能够合理控制支出。`
        });
      } else if (savingRate >= 0) {
        insights.push({
          type: 'saving_rate',
          level: 'warning',
          title: '储蓄意识偏弱',
          content: `储蓄率仅${savingRate.toFixed(1)}%，支出与收入基本持平，建议加强储蓄意识。`
        });
      } else {
        insights.push({
          type: 'saving_rate',
          level: 'danger',
          title: '⚠️ 入不敷出',
          content: `本期支出超过收入¥${Math.abs(netIncome).toFixed(2)}，需要紧急控制消费。`
        });
      }

      // 3. 主要消费类别
      if (categoryStats.length > 0) {
        const topCategory = categoryStats[0];
        const topPercentage = (parseFloat(topCategory.amount || 0) / parseFloat(stats.total_expense || 1) * 100).toFixed(1);
        
        const categoryLabels = {
          '餐饮': '餐饮',
          '购物': '购物',
          '交通': '交通出行',
          '娱乐': '娱乐',
          '生活': '生活服务',
          '学习': '学习教育'
        };

        insights.push({
          type: 'main_category',
          title: '日常消费特征',
          content: `${categoryLabels[topCategory.category] || topCategory.category}是您的主要支出类别，占比${topPercentage}%（¥${parseFloat(topCategory.amount || 0).toFixed(2)}），平均每笔¥${avgExpense.toFixed(2)}。`
        });
      }

      // 4. 高频商户
      if (topMerchants.length > 0) {
        const merchantNames = topMerchants.slice(0, 3).map(m => m.merchant).join('、');
        insights.push({
          type: 'merchants',
          title: '常去商户',
          content: `您经常在${merchantNames}等地消费，表明您的消费习惯较为固定。`
        });
      }

      // 5. 消费频次洞察
      const daysInPeriod = Math.ceil((new Date(endDate) - new Date(startDate)) / (1000 * 60 * 60 * 24)) + 1;
      const dailyExpenseCount = stats.expense_count / daysInPeriod;
      
      if (dailyExpenseCount >= 5) {
        insights.push({
          type: 'frequency',
          level: 'high',
          title: '消费频次较高',
          content: `平均每天记账${dailyExpenseCount.toFixed(1)}笔，消费频次较高，多为小额支出。建议整合消费，减少不必要的零散开支。`
        });
      } else if (dailyExpenseCount >= 2) {
        insights.push({
          type: 'frequency',
          level: 'normal',
          title: '消费频次适中',
          content: `平均每天记账${dailyExpenseCount.toFixed(1)}笔，消费频次适中，节奏较为规律。`
        });
      }

      // 6. 收入来源分析
      if (stats.total_income > 0) {
        // 简单判断收入模式（可以进一步细化）
        if (stats.income_count <= 3 && stats.total_income >= stats.total_expense * 0.7) {
          insights.push({
            type: 'income_pattern',
            title: '收入依赖家庭支持',
            content: `收入笔数较少且金额集中，推测主要来自家庭支持或固定来源。建议在学习之余尝试兼职，增加自主收入。`
          });
        }
      }

      return {
        summary: insights,
        statistics: {
          total_records: stats.total_count,
          total_income: parseFloat(stats.total_income || 0),
          total_expense: parseFloat(stats.total_expense || 0),
          net_income: parseFloat(netIncome.toFixed(2)),
          saving_rate: parseFloat(savingRate.toFixed(1)),
          avg_expense: parseFloat(avgExpense.toFixed(2)),
          daily_expense_count: parseFloat(dailyExpenseCount.toFixed(1))
        },
        top_merchants: topMerchants.map(m => ({
          merchant: m.merchant,
          count: m.count,
          amount: parseFloat(m.amount.toFixed(2))
        }))
      };
    } catch (error) {
      console.error('消费模式总结生成失败:', error);
      throw error;
    }
  }
}

module.exports = HabitAnalyzer;

